package media

import (
	"apiExample/auth"
	"apiExample/common"
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
)

type uploadResult struct {
	Result int32 `json:"result"`
	Errmsg string `json:"errmsg"`
	MediaId string `json:"media_id"`
	CreatedAt string `json:"created_at"`
}
/*
	5.1 上传多媒体文件
*/
func UploadMedia(fileName string, fileType string) (string, error) {
	file, err := os.Open(fileName)
	if err != nil {
		return "", err
	}
	defer file.Close()
	fi, err := file.Stat()
	if err != nil {
		return "", err
	}

	token, err := auth.GetAccessToken()
	if err != nil {
		return  "", err
	}

	url := fmt.Sprintf("%s/cgi-bin/file/upload?access_token=%s&type=%s", common.ApiUrl, token, fileType)
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	_, err = writer.CreateFormFile("filename", fi.Name())
	if err != nil {
		return "", err
	}
	//这里加---------的原因是服务端校验添加的
	boundary := fmt.Sprintf("------------------------%s--", writer.Boundary())
	closeBuf := bytes.NewBufferString(fmt.Sprintf("\r\n%s\r\n", boundary))
	reqReader := io.MultiReader(body, file, closeBuf)

	req, err := http.NewRequest("POST", url, reqReader)
	if err != nil {
		return "", err
	}

	req.Header.Add("Content-Type", "multipart/form-data; boundary="+ boundary)
	req.ContentLength = fi.Size() + int64(body.Len()) + int64(closeBuf.Len())
	rsp, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	rspBody, err := ioutil.ReadAll(rsp.Body)
	if err != nil {
		return  "", errors.New(fmt.Sprintf("Get %s server, read http rsp body failed! err=%v", url, err))
	}
	//fmt.Println(string(rspBody))
	rspResult := &uploadResult{}
	err = json.Unmarshal(rspBody, rspResult)
	if err != nil {
		return "",errors.New(fmt.Sprintf("Get %s server, umarshal body failed! err=%v", url, err))
	}
	return rspResult.MediaId, nil

}

/*
	5.2.1 直接下载文件
*/
func DownloadMedia(mediaId string, outFile string) error {
	token, err := auth.GetAccessToken()
	if err != nil {
		return  err
	}

	url := fmt.Sprintf("%s/cgi-bin/file/get?access_token=%s&media_id=%s", common.ApiUrl, token, mediaId)
	rsp, err := http.Get(url)
	if err != nil {
		return errors.New(fmt.Sprintf("Get %s from server, http error = %v", url, err))
	}
	defer rsp.Body.Close()
	//fmt.Println(rsp)
	if rsp.StatusCode != 200 {
		return errors.New(fmt.Sprintf("Get %s server, http response status not 200, StatusCode=%v", url, rsp.StatusCode))
	}

	out, err := os.Create(outFile)
	if err != nil {
		return err
	}
	defer out.Close()

	writer := bufio.NewWriter(out)
	_ ,err = io.Copy(writer, rsp.Body)
	if err != nil {
		return err
	}
	err = writer.Flush()
	if err != nil{
		return err
	}
	return nil
}


type downloadUrlRequst struct {
	MediaId []string `json:"media_id"`
}

type UrlsInfo struct {
	Result int32 `json:"result"`
	Url string `json:"url"`
	MediaId string `json:"media_id"`
}

type downloadUrlResult struct {
	Result int32 `json:"result"`
	Errmsg string `json:"errmsg"`
	Urls []*UrlsInfo `json:"urls"`
}

/*
  5.2.2 获取文件下载url
*/
func DownloadMediaUrl(medias []string) ([]*UrlsInfo, error){
	token, err := auth.GetAccessToken()
	if err != nil {
		return  nil, err
	}

	url := fmt.Sprintf("%s/cgi-bin/file/url_batch?access_token=%s", common.ApiUrl, token)

	req := &downloadUrlRequst{
		MediaId: medias,
	}

	rsp := &downloadUrlResult{}
	if err := common.HttpPostData(url, req ,rsp); err != nil {
		return rsp.Urls, err
	}

	if rsp.Result != 0 {
		return  rsp.Urls, errors.New(fmt.Sprintf("Server respone not ok, result=%v,msg=%s", rsp.Result, rsp.Errmsg))
	}
	return rsp.Urls, nil
}